﻿using AutoMapper;
using ImoviesBlazorAntPro.Server.Helpers;
using ImoviesBlazorAntPro.Server.Repository;
using ImoviesBlazorAntPro.Shared.Dtos;
using ImoviesBlazorAntPro.Shared.Entities;
using ImoviesBlazorAntPro.Shared.Utils;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace ImoviesBlazorAntPro.Server.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class MovieController : ControllerBase
    {
        private readonly IMovieRepository _movieRepository;
        private readonly IMapper _mapper;

        public MovieController(IMovieRepository movieRepository, IMapper mapper)
        {
            this._movieRepository = movieRepository;
            this._mapper = mapper;
        }


        /// <summary>
        /// 获取所有年份
        /// </summary>
        /// <returns></returns>
        [HttpGet("years")]
        public ActionResult<List<uint>> GetAllYears()
        {
            // 先从缓存中读取
            var cacheYears = CacheUtils.GetData<List<uint>>(CacheKeyConst.MOVIE_ALL_YEARS);
            if (cacheYears != null)
            {
                return Ok(cacheYears);
            }

            var years = _movieRepository.GetAllYears();
            // 设置缓存
            CacheUtils.SetData<List<uint>>(CacheKeyConst.MOVIE_ALL_YEARS, years.Distinct().ToList());

            return Ok(years);
        }

        /// <summary>
        /// 分页获取数据
        /// </summary>
        /// <param name="pageSize">页大小</param>
        /// <param name="pageNum">页码</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ActionResult<PaginationList<MovieDataList>>> GetList([FromQuery] int pageSize, [FromQuery] int pageNum)
        {
            string cacheKey = $"{CacheKeyConst.MOVIE_PAGINATION_LIST}{pageSize}{pageNum}";
            // 先从缓存中读取
            var cacheData = CacheUtils.GetData<PaginationList<MovieDataList>>(cacheKey);
            if (cacheData != null)
            {
                return Ok(cacheData);
            }

            var ms = await _movieRepository.GetListAsync(pageSize, pageNum);

            var msDtolist = _mapper.Map<List<MovieDto>>(ms);
            List<MovieDataList> list = new List<MovieDataList>();
            var gy = msDtolist.GroupBy(x => x.Year).ToList();

            foreach (var item in gy)
            {
                list.Add(new MovieDataList
                {
                    Year = item.Key,
                    List = item.ToList()
                });
            }

            var total = _movieRepository.GetTotal();
            var data = new PaginationList<MovieDataList>
            {
                Data = list,
                Total = total,
            };

            // 设置缓存
            CacheUtils.SetData<PaginationList<MovieDataList>>(cacheKey, data);

            return Ok(data);
        }


        /// <summary>
        /// 仅获取所有视频列表
        /// </summary>
        /// <param name="pageSize"></param>
        /// <param name="pageNum"></param>
        /// <returns></returns>
        [HttpGet("list")]
        public async Task<ActionResult<PaginationList<MovieDto>>> GetPureList([FromQuery] int pageSize, [FromQuery] int pageNum)
        {
            //admin管理端请求
            if (Request.Headers.ContainsKey("X-Req-Origin"))
            {
                var ts1 = await _movieRepository.GetPureListAsync(pageSize, pageNum);
                var tsDtolist1 = _mapper.Map<List<MovieDto>>(ts1);
                var total1 = _movieRepository.GetTotal();
                var data1 = new PaginationList<MovieDto>
                {
                    Data = tsDtolist1,
                    Total = total1,
                };
                return Ok(data1);
            }


            // 先从缓存中读取
            var cacheData = CacheUtils.GetData<PaginationList<MovieDto>>(CacheKeyConst.MOVIE_ALL_PURE_LIST);
            if (cacheData != null)
            {
                return Ok(cacheData);
            }

            var ts = await _movieRepository.GetPureListAsync(pageSize, pageNum);
            var tsDtolist = _mapper.Map<List<MovieDto>>(ts);
            var total = _movieRepository.GetTotal();
            var data = new PaginationList<MovieDto>
            {
                Data = tsDtolist,
                Total = total,
            };
            // 设置缓存
            CacheUtils.SetData<PaginationList<MovieDto>>(CacheKeyConst.MOVIE_ALL_PURE_LIST, data);

            return Ok(data);
        }


        /// <summary>
        /// 获取所有视频列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("all")]
        public async Task<ActionResult<List<MovieDto>>> GetAll()
        {
            //admin管理端请求
            if (Request.Headers.ContainsKey("X-Req-Origin"))
            {
                var list1 = await _movieRepository.GetAllListAsync();
                return Ok(_mapper.Map<List<MovieDto>>(list1));
            }

            // 先从缓存中读取
            var cacheData = CacheUtils.GetData<List<MovieDto>>(CacheKeyConst.MOVIE_ALL_LIST);
            if (cacheData != null)
            {
                return Ok(cacheData);
            }

            var list = await _movieRepository.GetAllListAsync();
            var data = _mapper.Map<List<MovieDto>>(list);

            // 设置缓存
            CacheUtils.SetData<List<MovieDto>>(CacheKeyConst.MOVIE_ALL_LIST, data);

            return Ok(data);
        }


        /// <summary>
        /// 获取视频链接列表
        /// </summary>
        /// <param name="vid"></param>
        /// <returns></returns>
        [HttpGet("vlist/{vid}")]
        public async Task<ActionResult<List<MovieVlinkDto>>> GetVlinkList(string vid)
        {
            //admin管理端请求
            if (Request.Headers.ContainsKey("X-Req-Origin"))
            {
                var vlinks1 = await _movieRepository.GetVlinkList(vid);
                return Ok(_mapper.Map<List<MovieVlinkDto>>(vlinks1));
            }

            string cacheKey = $"{CacheKeyConst.MOVIE_PLAYLINK_LIST}{vid}";
            // 先从缓存中读取
            var cacheData = CacheUtils.GetData<List<MovieVlinkDto>>(cacheKey);
            if (cacheData != null)
            {
                return Ok(cacheData);
            }

            var vlinks = await _movieRepository.GetVlinkList(vid);
            var data = _mapper.Map<List<MovieVlinkDto>>(vlinks);

            // 设置缓存
            CacheUtils.SetData<List<MovieVlinkDto>>(cacheKey, data.ToList());

            return Ok(data);
        }


        /// <summary>
        /// 视频搜索
        /// </summary>
        /// <param name="keyword"></param>
        /// <returns></returns>
        [HttpGet("search")]
        public ActionResult<List<MovieDto>> Search([FromQuery] string keyword)
        {
            var list = _movieRepository.Search(keyword);
            var data = _mapper.Map<List<MovieDto>>(list);
            return Ok(data);
        }


        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="movie"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public ActionResult AddMovie([FromBody] MovieForCreateDto movie)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest();
            }
            var a = _mapper.Map<Movie>(movie);
            byte[] bytes = MD5.HashData(Encoding.UTF8.GetBytes(movie.Name));
            a.Id = BitConverter.ToString(bytes).Replace("-", "");
            _movieRepository.AddMovie(a);
            bool res = _movieRepository.Save();
            if (!res)   //保存失败
            {
                Response.StatusCode = 500;
                return Content("操作失败");
            }
            return Ok();
        }


        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="movie"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPut]
        public ActionResult UpdateMovie([FromBody] MovieForUpdateDto movie)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest();
            }
            var a = _mapper.Map<Movie>(movie);
            _movieRepository.UpdateMovie(a);
            bool res = _movieRepository.Save();
            if (!res)   //保存失败
            {
                Response.StatusCode = 500;
                return Content("操作失败");
            }
            return Ok();
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Authorize]
        [HttpDelete("{id}")]
        public async Task<ActionResult> DeleteMovie([FromRoute] string id)
        {
            await _movieRepository.DeleteMovie(id);
            bool res = _movieRepository.Save();
            if (!res)   //保存失败
            {
                Response.StatusCode = 500;
                return Content("操作失败");
            }
            return Ok();
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost("{batchDetele}")]
        public ActionResult DeleteBatch([FromBody] List<string> ids)
        {
            _movieRepository.DeleteBatch(ids);
            bool res = _movieRepository.Save();
            if (!res)   //保存失败
            {
                Response.StatusCode = 500;
                return Content("操作失败");
            }
            return Ok();
        }
    }
}
